import os
import time
from datetime import datetime
import logging
import shutil
from pathlib import Path
import re


class FileRenamer:
    def __init__(self, download_dir, log_file="file_operations.log"):
        """
        初始化文件重命名器
        :param download_dir: 下载文件夹路径
        :param log_file: 日志文件路径
        """
        self.download_dir = Path(download_dir)
        self.setup_logging(log_file)

    def setup_logging(self, log_file):
        """设置日志配置"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler(log_file, encoding='utf-8'),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)

    def get_latest_file(self, skip_partial=True):
        """
        获取下载文件夹中最新的文件
        :param skip_partial: 是否跳过未完成的下载文件
        :return: 最新文件的Path对象或None
        """
        try:
            files = []
            for file_path in self.download_dir.iterdir():
                if file_path.is_file():
                    if skip_partial and self._is_partial_download(file_path.name):
                        continue
                    files.append((file_path, file_path.stat().st_mtime))

            if not files:
                self.logger.warning(f"在文件夹 {self.download_dir} 中未找到文件")
                return None

            latest_file = max(files, key=lambda x: x[1])[0]
            self.logger.info(f"找到最新文件: {latest_file}")
            return latest_file

        except Exception as e:
            self.logger.error(f"获取最新文件时出错: {str(e)}")
            return None

    def _is_partial_download(self, filename):
        """检查是否是未完成的下载文件"""
        partial_extensions = {'.crdownload', '.tmp', '.part'}
        return any(filename.endswith(ext) for ext in partial_extensions)

    def _get_next_available_name(self, base_path):
        """
        获取下一个可用的文件名（添加序号）
        例如: 如果 test.txt 存在，返回 test(1).txt，如果test(1).txt也存在，返回test(2).txt
        """
        if not base_path.exists():
            return base_path

        stem = base_path.stem
        suffix = base_path.suffix
        parent = base_path.parent

        # 检查文件名是否已经有序号
        match = re.match(r"(.*?)\((\d+)\)$", stem)
        if match:
            # 如果已经有序号，获取基本名称
            stem = match.group(1).rstrip()

        counter = 1
        while True:
            new_name = f"{stem}({counter}){suffix}"
            new_path = parent / new_name
            if not new_path.exists():
                return new_path
            counter += 1

    def rename_latest_file(self, new_name, max_wait=30, check_interval=1):
        """
        重命名最新文件
        :param new_name: 新文件名
        :param max_wait: 最大等待时间（秒）
        :param check_interval: 检查间隔（秒）
        :return: 是否成功重命名
        """
        try:
            start_time = time.time()
            while time.time() - start_time < max_wait:
                latest_file = self.get_latest_file()
                if not latest_file:
                    self.logger.warning("未找到可重命名的文件，等待中...")
                    time.sleep(check_interval)
                    continue

                # 确保新文件名有正确的扩展名
                if latest_file.suffix and not new_name.endswith(latest_file.suffix):
                    new_name = new_name + latest_file.suffix

                new_path = latest_file.parent / new_name

                # 检查文件是否被锁定
                if self._is_file_locked(latest_file):
                    self.logger.info(f"文件 {latest_file.name} 仍在使用中，等待...")
                    time.sleep(check_interval)
                    continue

                # 如果文件已存在，获取带序号的新文件名
                if new_path.exists():
                    new_path = self._get_next_available_name(new_path)
                    self.logger.info(f"文件名已存在，使用新名称: {new_path.name}")

                # 执行重命名
                shutil.move(str(latest_file), str(new_path))
                self.logger.info(f"成功将文件 '{latest_file.name}' 重命名为 '{new_path.name}'")
                return True

            self.logger.error(f"重命名超时，超过{max_wait}秒")
            return False

        except Exception as e:
            self.logger.error(f"重命名文件时出错: {str(e)}")
            return False

    def _is_file_locked(self, filepath):
        """检查文件是否被锁定"""
        try:
            with open(filepath, 'ab') as _:
                pass
            return False
        except (IOError, PermissionError):
            return True


# 使用示例
def main():
    # 使用示例
    download_path = r"C:\Users\YourUsername\Downloads"  # 替换为实际下载路径
    renamer = FileRenamer(download_path)

    # 重命名文件
    success = renamer.rename_latest_file("测试文件")

    if success:
        print("文件重命名成功！")
    else:
        print("文件重命名失败，请查看日志了解详情。")


# 测试函数
def test_renamer():
    """测试重命名功能"""
    # 创建测试目录
    test_dir = Path("test_downloads")
    test_dir.mkdir(exist_ok=True)

    try:
        # 创建测试文件
        test_files = [
            "test.txt",
            "test(1).txt",
            "test(2).txt"
        ]

        for file_name in test_files:
            with open(test_dir / file_name, "w") as f:
                f.write("test content")

        # 初始化重命名器
        renamer = FileRenamer(test_dir)

        # 测试重命名
        success = renamer.rename_latest_file("test.txt")

        # 验证结果
        if success:
            print("测试成功：文件被正确重命名")
        else:
            print("测试失败：文件重命名失败")

    finally:
        # 清理测试文件
        shutil.rmtree(test_dir)

    return success


